using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

using Affirma.ThreeSharp;
using Affirma.ThreeSharp.Query;

namespace Affirma.CloudFront.AdminTool
{
    public partial class frmAccountManager : Form
    {
        #region Events

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnUseAccount_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.lstAccounts.SelectedIndex > -1)
                {
                    AwsAccount selectedAccount = AccountManager.Instance.GetAwsAccountByName(this.lstAccounts.SelectedItem.ToString());
                    
                    if (selectedAccount != null)
                    {
                        selectedAccount.IsSelected = true;
                        AccountManager.Instance.SaveAccount(selectedAccount);
                    }

                    this.Close();
                }
                else
                {
                    MessageBox.Show("Please select an account.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void btnNewAccount_Click(object sender, EventArgs e)
        {
            this.InitNewAccount();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(this.txtAccountName.Text.Trim())
                    && !string.IsNullOrEmpty(this.txtAccessKeyID.Text.Trim())
                    && !string.IsNullOrEmpty(this.txtSecretAccessKey.Text.Trim()))
                {
                    bool isUniqueAccountName = true;                    
                    foreach (string accountName in this.lstAccounts.Items)
                    {
                        AwsAccount account = AccountManager.Instance.GetAwsAccountByName(accountName);
                        if (account.ID.ToString() != this.lblAccountId.Text
                            && account.Name.ToLower() == this.txtAccountName.Text.Trim().ToLower())
                        {
                            isUniqueAccountName = false;
                            break;
                        }
                    }

                    if (isUniqueAccountName)
                    {
                        if (!string.IsNullOrEmpty(this.lblAccountId.Text))
                        {
                            AwsAccount newAccount = null;                            
                            foreach (SettingsProperty property in Properties.Settings.Default.Properties)
                            {
                                if (property.Name.Contains(AccountManager.SettingPrefix)
                                    && ((AwsAccount)property.DefaultValue).ID == this.lblAccountId.Text)
                                {
                                    newAccount = (AwsAccount)property.DefaultValue;
                                    break;
                                }
                            }

                            if (newAccount != null)
                            {
                                newAccount.Name = this.txtAccountName.Text.Trim();
                                newAccount.AccessKey = this.txtAccessKeyID.Text.Trim();
                                newAccount.SecretKey = AccountManager.Instance.Encrypt(this.txtSecretAccessKey.Text.Trim());
                                newAccount.UseS3Https = this.chkEnableSSL.Checked;
                                newAccount.IsSelected = this.chkUseAsDefault.Checked;

                                AccountManager.Instance.SaveAccount(newAccount);

                                this.lstAccounts.Items[this.lstAccounts.SelectedIndex] = newAccount.ToString();                                
                            }
                            else
                            {
                                Exception ex = new Exception("The property collection has been corrupted.");
                                throw (ex);
                            }
                        }
                        else
                        {
                            AwsAccount newAccount = new AwsAccount(this.txtAccountName.Text.Trim(), this.txtAccessKeyID.Text.Trim(), AccountManager.Instance.Encrypt(this.txtSecretAccessKey.Text.Trim()));
                            newAccount.UseS3Https = this.chkEnableSSL.Checked;
                            newAccount.IsSelected = this.chkUseAsDefault.Checked;
                            AccountManager.Instance.SaveAccount(newAccount);
                            
                            this.lstAccounts.Items.Add(newAccount.ToString());
                        }
                    }
                    else
                    {
                        MessageBox.Show("Account name must be unique.");
                        this.txtAccountName.SelectAll();
                    }
                }
                else
                {
                    MessageBox.Show("All fields are required.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.lstAccounts.SelectedIndex > -1)
                {
                    DialogResult result = MessageBox.Show(this, "Delete the selected account?", "Delete Account", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (result == DialogResult.Yes)
                    {
                        AwsAccount accountToDelete = AccountManager.Instance.GetAwsAccountByName(this.lstAccounts.SelectedItem.ToString());
                        if (accountToDelete != null)
                        {
                            AccountManager.Instance.DeleteAccount(accountToDelete);
                            object selectItem = this.lstAccounts.SelectedItem;
                            this.lstAccounts.SelectedIndex = -1;
                            this.lstAccounts.Items.Remove(selectItem);
                            this.lstAccounts.Refresh();
                            this.InitNewAccount();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void lstAccounts_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.lstAccounts.SelectedIndex > -1)
                {
                    AwsAccount selectedAccount = AccountManager.Instance.GetAwsAccountByName(this.lstAccounts.SelectedItem.ToString());
                    if (selectedAccount != null)
                    {
                        this.lblAccountId.Text = selectedAccount.ID.ToString();
                        this.txtAccountName.Text = selectedAccount.Name;
                        this.txtAccessKeyID.Text = selectedAccount.AccessKey;
                        this.txtSecretAccessKey.Text = AccountManager.Instance.Decrypt(selectedAccount.SecretKey);
                        this.chkEnableSSL.Checked = selectedAccount.UseS3Https;
                        this.chkUseAsDefault.Checked = selectedAccount.IsSelected;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void frmAccountManager_Load(object sender, EventArgs e)
        {
            try
            {
                int selectedAccountIndex = -1;
                List<AwsAccount> savedAccounts = AccountManager.Instance.GetSavedAccounts();

                if (savedAccounts.Count > 0)
                {
                    for (int i = 0; i < savedAccounts.Count; i++)
                    {
                        AwsAccount account = savedAccounts[i];
                        SettingsProperty prop = new SettingsProperty(AccountManager.SettingPrefix + account.ID.ToString());

                        prop.DefaultValue = account;
                        if (Properties.Settings.Default.Properties[AccountManager.SettingPrefix + account.ID] == null)
                            Properties.Settings.Default.Properties.Add(prop);
                        else
                            Properties.Settings.Default.Properties[AccountManager.SettingPrefix + account.ID].DefaultValue = account;

                        Properties.Settings.Default.Save();

                        this.lstAccounts.Items.Add(account.ToString());

                        if (account.IsSelected)
                            selectedAccountIndex = i;
                    }

                    if (selectedAccountIndex > -1)
                        this.lstAccounts.SelectedIndex = selectedAccountIndex;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (this.lstAccounts.Items.Count == 1)
            {
                this.lstAccounts.SelectedIndex = 0;
            }

            base.OnClosing(e);
        }

        #endregion

        #region Constructors

        public frmAccountManager()
        {
            InitializeComponent();
            this.Load += new EventHandler(frmAccountManager_Load);
        }

        #endregion

        #region Methods

        private void InitNewAccount()
        {
            try
            {
                this.lstAccounts.SelectedIndex = -1;
                this.txtAccountName.Text = string.Empty;
                this.txtAccessKeyID.Text = string.Empty;
                this.txtSecretAccessKey.Text = string.Empty;
                this.lblAccountId.Text = string.Empty;
                this.chkEnableSSL.Checked = true;
                this.chkUseAsDefault.Checked = false;
                this.txtAccountName.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        #endregion
    }
}